import { TransformNode, Utils } from 'babylon-lib/index';
import { DefaultStage } from '../default-stage';
import { Mesh } from '@babylonjs/core/Meshes/mesh';
import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
import { Color3 } from '@babylonjs/core/Maths/math.color';


/**
 * 部队名称
 */
interface ITroopOptions {
    name: string
}


/**
 * 部队，即战斗单位，一个势力可以有任意数量的部队，但所有部队人数的总量不能超过势力军队数量。
 * 部队可用的操作有：创建、调遣、分解、联合、解散；
 * 创建：
 *      调派建筑或其他部队人口组成新的部队。当势力人口或征兵比例发生变化时，势力的军队数量
 *      会自动增加，超过当前部队人口总量，这时多出来的这一部分军队会自动分配到建筑并创建一支
 *      卫戍部队。
 * 调遣：
 *      指定部队的目的地和行进路线，部队移动到目的地进行等待或战斗。
 * 分解：
 *      分出一部分人口组成新的部队。
 * 联合：
 *      将若干个部队合并为一个新的部队。
 * 解散：
 *      将部队的部分或全部人口转换为平民，转换的平民将按人口比例分配到各建筑。
 */
class Troop {

    public readonly id = Utils.id;
    public readonly container: TransformNode;

    private _stage: DefaultStage;
    private _options: ITroopOptions;
    private _body: InstancedMesh;
    private _pickMesh: Mesh;

    private static _body: Mesh;
    private static _initializeBody(stage: DefaultStage): void {
        if (this._body) return;
        const m = MeshBuilder.CreatePlane('troopBody', { size: 1 }, stage.mainScene);
        m.registerInstancedBuffer('color', 3);
        m.isPickable = false;
        m.isVisible = false;
        const material = new StandardMaterial('troopBodyMaterial', stage.mainScene);
        material.disableLighting = true;
        material.emissiveColor = Color3.FromHexString('#ffffff');
        m.material = material;
        this._body = m;
    }

    constructor(stage: DefaultStage, options: ITroopOptions) {
        Troop._initializeBody(stage);
        this._stage = stage;
        this._options = options;
        this.container = new TransformNode(this.id + 'TroopContainer', this._stage.mainScene);
        this._body = this.initializeMesh();
        this._pickMesh = this.initializePickMesh();
    }

    public get name(): string {
        return this._options.name;
    }

    public get pickMesh(): Mesh {
        return this._pickMesh;
    }

    private initializeMesh(): InstancedMesh {
        const m = Troop._body.createInstance(this.id + 'TroopMesh');
        m.instancedBuffers.color = Color3.FromHexString('#ffffff');
        m.alwaysSelectAsActiveMesh = true;
        m.isVisible = true;
        m.isPickable = true;
        m.parent = this.container;
        m.scaling.setAll(1);
        m.position.setAll(0);
        return m;
    }

    private initializePickMesh(): Mesh {
        const m = MeshBuilder.CreatePlane(this.name + 'PickMesh', { size: 1 }, this._stage.mainScene);
        m.parent = this.container;
        return m;
    }

}


export { Troop };